package cn.qianxun.meta.upload.service.impl;

import cn.qianxun.meta.common.core.utils.DateUtils;
import cn.qianxun.meta.common.core.utils.StringUtils;
import cn.qianxun.meta.common.oss.core.OssClient;
import cn.qianxun.meta.common.oss.properties.OssProperties;
import cn.qianxun.meta.common.core.exception.ServiceException;
import cn.qianxun.meta.common.core.exception.base.BaseException;
import cn.qianxun.meta.common.core.utils.uuid.IdUtils;
import cn.qianxun.meta.file.entity.SysFileRecord;
import cn.qianxun.meta.file.mapper.SysFileRecordMapper;
import cn.qianxun.meta.upload.service.IUploadService;
import cn.qianxun.meta.upload.vo.FlowableUploadVO;
import cn.qianxun.meta.upload.vo.UploadFileVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author fuzhilin
 * @Date 2023/9/6 11:42
 * @Description
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class UploadServiceImpl implements IUploadService {
    private final OssProperties ossProperties;

    private final SysFileRecordMapper sysFileRecordMapper;

    @Override
    public UploadFileVO uploadByBucketName(String bucketName, MultipartFile file) {
        if (StringUtils.isEmpty(bucketName)) {
            throw new ServiceException("bucketName不能为空");
        }
        String fileName = file.getOriginalFilename();
        String fileType = OssClient.getFileType(file.getOriginalFilename());
        if (StringUtils.isNotEmpty(ossProperties.getFileFormatWhite())) {
            if (!ossProperties.getFileFormatWhite().contains(fileType + ",")) {
                throw new ServiceException(StringUtils.format("文件格式({})非法，不允许上传。 ", fileName));
            }
        }
        String fileId = IdUtils.fastSimpleUUID();
        OssClient ossClient = new OssClient("oss", ossProperties);
        String fileDir = DateUtils.dateTimeYearMonth(new Date()) + "/";
        String path = fileDir + fileId + fileName;
        try {
            ossClient.upload(bucketName, file.getInputStream(), path, file.getContentType());
            SysFileRecord fileRecord = new SysFileRecord();
            fileRecord.setId(fileId);
            fileRecord.setBucketName(bucketName);
            fileRecord.setFileName(fileName);
            fileRecord.setFileDir(fileDir);
            fileRecord.setFilePath(path);
            fileRecord.setFileType(fileType);
            sysFileRecordMapper.insert(fileRecord);
            UploadFileVO fileVO = new UploadFileVO();
            fileVO.setBucketName(bucketName);
            fileVO.setFileName(fileName);
            fileVO.setFileDir(fileDir);
            fileVO.setUrl(path);
            fileVO.setFileId(fileId);
            fileVO.setType(fileType);
            return fileVO;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("上传失败");
        }
    }

    @Override
    public void downloadByFileId(String fileId, HttpServletResponse response) {
        if (StringUtils.isEmpty(fileId)) {
            throw new BaseException("文件id不能为空");
        }
        SysFileRecord fileRecord = sysFileRecordMapper.selectById(fileId);
        if (StringUtils.isNull(fileRecord)) {
            throw new ServiceException("文件不存在");
        }
        String fileName = fileRecord.getFileDir() + fileRecord.getId() + fileRecord.getFileName();
        try {
            OssClient ossClient = new OssClient("oss", ossProperties);
            ossClient.download(fileRecord.getBucketName(), fileName, response);
        } catch (Exception e) {
            log.error("下载文件失败", e);
            throw new ServiceException("下载文件失败");
        }
    }

    @Override
    public String getPreviewByFileId(String fileId) {
        SysFileRecord fileRecord = sysFileRecordMapper.selectById(fileId);
        if (StringUtils.isNull(fileRecord)) {
            throw new ServiceException("文件不存在");
        }
        String fileName = fileRecord.getFileDir() + fileRecord.getId() + fileRecord.getFileName();
        try {
            OssClient ossClient = new OssClient("oss", ossProperties);
            return ossClient.getPrivateUrl(fileRecord.getBucketName(), fileName, 1800);
        } catch (Exception e) {
            log.error("获取预览地址失败", e);
            throw new ServiceException("获取预览地址失败");
        }
    }

    @Override
    public FlowableUploadVO authUploadByBucketName(String bucketName, MultipartFile file) {
        UploadFileVO uploadFileVO = uploadByBucketName(bucketName, file);
        FlowableUploadVO uploadVO = new FlowableUploadVO();
        uploadVO.setName(uploadFileVO.getFileName());
        try {
            OssClient ossClient = new OssClient("oss", ossProperties);
            String path = uploadFileVO.getFileDir() + uploadFileVO.getFileId() + uploadFileVO.getFileName();
            uploadVO.setFileKey(path);
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("fileKey", path);
            String privateUrl = ossClient.getPrivateUrl(uploadFileVO.getBucketName(), path, 1800, paramMap);
            uploadVO.setUrl(privateUrl);
        } catch (Exception e) {
            log.error("预览文件失败", e);
            throw new ServiceException("预览文件失败");
        }
        return uploadVO;
    }
}
